/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package webservices;

import Entities.Activereservation;
import Entities.Resource;
import Entities.User;
import constants.Consts;
import helpers.Debug;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.TypedQuery;
import javax.ws.rs.Path;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import rhserver.MainController;
import rhserver.MyLogger;

/**
 * REST Web Service
 *
 * @author Bari
 */
@Path("activate")
public class ActivateResource extends AbstractWebService {

    @Context
    private UriInfo context;

    public ActivateResource() throws Exception {
        super();
    }

    private Activereservation getAlreadyActiveResource(Resource resource, EntityManager em) {
        TypedQuery<Activereservation> query = em.createNamedQuery("Activereservation.findByResourceid", Activereservation.class);
        query.setParameter("resourceid", resource.getId());
        List<Activereservation> reservations = query.getResultList();
        if (reservations.size() > 0) {
            return reservations.get(0);
        } else {
            return null;
        }
    }

    private synchronized boolean jpaActivateResource(String androidId, Resource resource, long activationLength,EntityManager em) {
        Date startDate = MainController.getInstance().getCurrentDate();
        User user = getLocalUser(androidId, em);
        Debug.logMessage("getLocalUserId  id:", user.getId());
        Activereservation reservation = getAlreadyActiveResource(resource, em);
        
        EntityTransaction tx = em.getTransaction();
        tx.begin();
        if (reservation != null) {//Resource already active. changing deactivate time
            
            long deactivateAt = reservation.getEndtime().getTime() + activationLength;
            Date endDate = new Date(deactivateAt);
            reservation.setEndtime(endDate);
            Debug.logMessage("jpaActivateResource Old reservation:", reservation.toString());
            em.persist(reservation);
            tx.commit();
            MyLogger.logResourceStart(resource, user, startDate, endDate,em);
            return true;
        } else {//Resource not active, now activating

            
            Date endDate = new Date(MainController.getInstance().getCurrentDate().getTime() + activationLength);


            reservation = new Activereservation();
            reservation.setStarttime(startDate);
            reservation.setEndtime(endDate);
            reservation.setResourceid(resource);
            reservation.setUserid(user);

            em.persist(reservation);
            tx.commit();
            MainController.getInstance().startResourceTimer(activationLength, reservation.getId(), resource);
            MyLogger.logResourceStart(resource, user, startDate, endDate,em);
            return true;
        }
    }

    private boolean restartResource(String androidId, Resource resource,EntityManager em) {
        
        User user = getLocalUser(androidId, em);
        Activereservation reservation = getAlreadyActiveResource(resource, em);
        if (reservation!=null)
        {
            if (reservation.getUser()==user)
            {
                MainController.getInstance().smsRestartResource(resource);
                Debug.logMessage("restartResource", "Restarting: "+resource.getName());
                return true;
            }
            else
            {
                return false;
            }
            
        }
        else
        {
            return false;
        }
    }

    @Override
    protected String processJsonMessage(String jsonMessage) {
         EntityManager em=MainController.getInstance().getEntityManager();
        JSONObject response = new JSONObject();
        try {
            JSONObject requestJson = new JSONObject(jsonMessage);
            long resourceId = requestJson.getLong(Consts.RESOURCE_ID);
           
             Resource resource=getResourceById(resourceId, em);
            String userId = requestJson.getString(Consts.USER_ID);
            int resourceStartMode = requestJson.getInt(Consts.RESOURCE_START_MODE);
            if (resourceStartMode == Consts.RESOURCE_START) {
                
                long activationLength = Math.round(requestJson.getDouble(Consts.RESERVATION_LENGTH) * 60 * 60 * 1000);
                Debug.logMessage("activate", "category id: " + resourceId);
               
                boolean activated = jpaActivateResource(userId, resource, activationLength,em);

                if (activated) {
                    long clientTIme=requestJson.getLong(Consts.CLIENT_TIME);
                    response.put(Consts.CLIENT_TIME,clientTIme);
                    response.put(Consts.JSON_MESSAGE_CODE, Consts.RESPONSE_CONFIRM);
                    response.put(Consts.RESERVATION_LENGTH,activationLength);
                    response.put(Consts.SERVER_TIME,MainController.getInstance().getCurrentDate().getTime());
                    
                } else {
                    response.put(Consts.JSON_MESSAGE_CODE, Consts.RESPONSE_ERROR);
                }
               
            } else if (resourceStartMode == Consts.RESOURCE_RESTART) {
                boolean restarted = restartResource(userId, resource,em);
                if (restarted) {
                    response.put(Consts.JSON_MESSAGE_CODE, Consts.RESPONSE_CONFIRM);
                } else {
                     response.put(Consts.JSON_MESSAGE_CODE, Consts.RESPONSE_ERROR);
                }

            } else //Failsafe , in case of some random code
            {
                response.put(Consts.JSON_MESSAGE_CODE, Consts.RESPONSE_ERROR);
            }
            em.close();
            return response.toString();
        } catch (JSONException ex) {
            try {
                Logger.getLogger(ActivateResource.class.getName()).log(Level.SEVERE, null, ex);
                response.put(Consts.JSON_MESSAGE_CODE, Consts.RESPONSE_ERROR);

            } catch (JSONException ex1) {
                Logger.getLogger(ActivateResource.class.getName()).log(Level.SEVERE, null, ex1);
            }
            em.close();
            return response.toString();
        }

    }
}
